# -*- coding: utf-8 -*-
"""
@Time    : 2024/7/13 14:51 
@Author  : ZhangShenao 
@File    : circle_reference.py 
@Desc    : 循环引用

默认情况下,循环引用的对象无法被垃圾回收

可以通过显式调用gc.collect()函数,触发垃圾回收,回收掉循环引用的对象

对于循环引用的情况,需要通过可达性分析算法,标记出不可达的对象,从而实现循环引用的回收
"""
import gc

from print_memory_usage import print_memory_usage


def circle_reference() -> None:
    """
    循环引用的情况
    即两个对象互相引用,但是它们没有被任何其它对象所引用
    """

    print_memory_usage('before a and b created')

    # 创建两个大对象
    a = [i for i in range(1000000)]
    b = [i for i in range(1000000)]

    # 让两个大对象互相引用
    a.append(b)
    b.append(a)

    print_memory_usage('after a and b created')


if __name__ == '__main__':
    # 默认情况下,循环引用的对象无法被垃圾回收
    # 因此这里即使方法调用已经结束了,但是局部变量a和b仍然无法被回收,因为它们的引用计数都不为0
    circle_reference()
    print_memory_usage('after function called')

    # 可以通过显式调用gc.collect()函数,触发垃圾回收,回收掉循环引用的对象
    gc.collect()
    print_memory_usage('after gc.collect() called')
